home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr37 / satsfaxt.zip / CCPUTILS.ZIP / CCSEND.C < prev    next >
Text File  |  1990-01-30  |  34KB  |  733 lines

  1. /*---------------------------------------------------------------------------*
  2.  *                               CCSEND.C                                    *
  3.  *---------------------------------------------------------------------------*
  4.  * The program manages the CC hardware as specified in the DCA/Intel         *
  5.  * CAS spec. All options, filenames and addresses are specified              *
  6.  * on the command line.                                                      *
  7.  *                                                                           *
  8.  * The following source code is intended to assist developers in             *
  9.  * creating applications which support the  DCA/Intel Communicating          *
  10.  * Applications Specification Version 1.0A. It is provided free of charge    *
  11.  * and on an as-is basis. THE IMPLIED WARRENTIES OF MERCHANTABILITY AND      *
  12.  * FITNESS FOR A PARTICULAR PURPOSE ARE SPECIFICALLY EXCLUDED. This source   *
  13.  * code may be modified, enhanced, copied and distributed with applications  *
  14.  * that support CAS on a royalty free basis.                                 *
  15.  *===========================================================================*/
  16. #include <stdio.h>
  17. #include <dos.h>
  18. #include <fcntl.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <io.h>
  22. #include <string.h>
  23. #include <malloc.h>
  24. #include <time.h>
  25. #include <io.h>
  26. #include "cas.h"                    /* Intel CAS header file.                */
  27. #include "parse.h"                  /* Command line parser header file.      */
  28. #include "util.h"                   /* CAS utilities header file.            */
  29.  
  30. #define TEMPLATE "CCXXXXXX"         /* Template for tempory filename.        */
  31.  
  32. /* Data structures for interfacing with CAS library. */
  33. SFTR *SFTRbuffer;                   /* Single File Transfer buffer.          */
  34. FTR *FTRbuffer[10];                 /* File Transfer buffer.                 */
  35. ECF *TCFbuffer;                     /* Task Control File buffer.             */
  36. EDB *EDBbuffer;                     /* External Data Block buffer.           */
  37.  
  38. FILE *ccout;                        /* Redirected stdout file.               */
  39.  
  40. /* Command line variables. */
  41. FileMode = FALSE;                   /* Transfer mode (file or FAX). */
  42. char *SendDate;                     /* Date to send. */
  43. char *SendTime;                     /* Time to send. */
  44. char *Cover;                        /* Cover page text. */
  45. char *CoverFile;                    /* Get cover text from file. */
  46. char *Phone;                        /* Phone number to dial. */
  47. char *Logo;                         /* Logo file path. */
  48. int DefLogo = FALSE;                /* Use default logo file (EDB). */
  49. int WideFont = FALSE;               /* 132 column font. */
  50. int HiRes = FALSE;                  /* High resolution (200x200 dpi) */
  51. int Help = FALSE;                   /* Show help message. */
  52. int RedirOut = FALSE;               /* Redirect output to file. */
  53.  
  54. /* Days per month - used for date checking. */
  55. int DaysPerMonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  56.  
  57. /* Argument table for command line processor. */
  58. STABLE SwitchTable[] =
  59. {
  60.     { 'M', STRING, (int *)&Cover     },
  61.     { 'm', STRING, (int *)&Cover     },
  62.     { 'C', STRING, (int *)&CoverFile },
  63.     { 'c', STRING, (int *)&CoverFile },
  64.     { 'D', STRING, (int *)&SendDate  },
  65.     { 'd', STRING, (int *)&SendDate  },
  66.     { 'T', STRING, (int *)&SendTime  },
  67.     { 't', STRING, (int *)&SendTime  },
  68.     { 'X', BOOL,          &FileMode  },
  69.     { 'x', BOOL,          &FileMode  },
  70.     { 'L', STRING, (int *)&Logo      },
  71.     { 'l', STRING, (int *)&Logo      },
  72.     { 'P', STRING, (int *)&Phone     },
  73.     { 'p', STRING, (int *)&Phone     },
  74.     { 'W', BOOL,   (int *)&WideFont  },
  75.     { 'w', BOOL,   (int *)&WideFont  },
  76.     { 'H', BOOL,   (int *)&HiRes     },
  77.     { 'h', BOOL,   (int *)&HiRes     },
  78.     { 'R', BOOL,          &RedirOut  },
  79.     { 'r', BOOL,          &RedirOut  },
  80.     { '?', BOOL,          &Help      }
  81. };
  82. #define TABLESIZE (sizeof(SwitchTable)/sizeof(STABLE))
  83.  
  84. char *DescTable[] =                 /* Help function description table. */
  85. {
  86.     "CCSEND (V1.0) Sends the file or fax specified by \"filename\". \"filename\" may\n",
  87.     "include a path (for example, c:\\aim\\guides.doc).\n\n",
  88.     "/P<number> is the phone number to send to. Use a comma for delay (for\n",
  89.     "example, /p9,555-1212). Characters such as \"-\" and \"( )\" are ignored.\n",
  90.     "The default is no cover page. A cover page will be sent if you specify /L,\n",
  91.     "/M, or /C.\n\n",
  92.     "Syntax: CCSEND filename... /P<number> [option...]\n\n"
  93. };
  94. #define DESCSIZE (sizeof(DescTable)/sizeof(DescTable[0]))
  95.  
  96. char *HelpTable[] =
  97. {
  98.      "  /L<filename> Logo file to send. \"default\" sends default logo.\n",
  99.      "  /M<text>     Cover page message, in quotes.\n",
  100.      "  /C<filename> Get cover page message from file.\n",
  101.      "  /D<mm/dd/yy> Date to send.\n",
  102.      "  /T<hh:mm>    Time to send.\n\n",
  103.      "  /X           Use file transfer (default is FAX).\n",
  104.      "  /W           Use wide (132 col) font (Only valid for FAX's).\n",
  105.      "  /H           Use high resolution fax (200x200 dpi).\n\n",
  106.      "  /R           Redirect output to file OUTPUT.CC.\n",
  107.      "  /?           Display help information.\n",
  108. };
  109. #define HELPSIZE (sizeof(HelpTable)/sizeof(HelpTable[0]))
  110.  
  111. /*---------------------------------------------------------------------------*
  112.  *                                  GetTime()                                *
  113.  *---------------------------------------------------------------------------*
  114.  * Function to convert ASCII time (hh:mm:ss) to DOS time format (packed      *
  115.  * word). Minimal error checking is performed for reasonable values for      *
  116.  * the hour, minute and second.                                              *
  117.  *---------------------------------------------------------------------------*
  118.  * Parameters:  char *gTime - CAS time structure.                            *
  119.  * Return:      Time in packed word format.                                  *
  120.  *---------------------------------------------------------------------------*/
  121. unsigned GetTime(char *cTime)
  122. {
  123.     int hour, minute, second;       /* Place to store normal time values.    */
  124.     unsigned w_time = 0;            /* Time packed into a single word.       */
  125.     char buffer[10];                /* Holds to string version of the time.  */
  126.  
  127.     if(cTime == NULL)
  128.         _strtime(buffer);
  129.     else
  130.         strcpy(buffer, cTime);
  131.  
  132.     hour = atoi(strtok(buffer, ":"));
  133.     minute = atoi(strtok(NULL, ":"));
  134.     second = atoi(strtok(NULL, ":")) / 2;
  135.  
  136.     /* Check for invalid time specification. */
  137.     if((hour < 0 || hour > 23) || (minute < 0 || minute > 59) || (second < 0 || second > 59))
  138.         CASError(CASBADTIME, TRUE, 0);
  139.  
  140.     /* Squeeze the time into a single word. */
  141.     w_time = second | (minute << 5) | (hour << 11);
  142.     return(w_time);
  143.  
  144. }
  145.  
  146. /*---------------------------------------------------------------------------*
  147.  *                                  GetDate                                  *
  148.  *---------------------------------------------------------------------------*
  149.  * Convert ASCII date (dd/mm/yy) to DOS date format (packed word). Minimal   *
  150.  * error checking is performed to check for reasonable values for day,       *
  151.  * month and year.                                                           *
  152.  *---------------------------------------------------------------------------*
  153.  * Paramters:   char *date - CAS date structure.                             *
  154.  * Return:      Date in packed word format.                                  *
  155.  *---------------------------------------------------------------------------*/
  156. unsigned GetDate(char *cDate)
  157. {
  158.     int month, day, year;           /* Place to hold the normal date values. */
  159.     unsigned w_date = 0;            /* Date packed into single word.         */
  160.     char buffer[10];                /* Holds string version of date.         */
  161.  
  162.     if(cDate == NULL)
  163.          _strdate(buffer);
  164.     else
  165.         strcpy(buffer, cDate);
  166.  
  167.     month = atoi(strtok(buffer, "/"));
  168.     day = atoi(strtok(NULL, "/"));
  169.     year = atoi(strtok(NULL, "/")) - 80;
  170.  
  171.     /* Check for invalid dates. */
  172.     if(month < 1 || month >12)
  173.         CASError(CASBADDATE, TRUE, 0);
  174.     if((((year + 1980) % 4) == 0) && (month == 2)) {
  175.         /* Leap year checking. */
  176.         if(day < 1 || day > 29)
  177.             CASError(CASBADDATE, TRUE, 0);
  178.     }
  179.     else {
  180.         /* Normal year checking. */
  181.         if(day < 1 || day > DaysPerMonth[month])
  182.             CASError(CASBADDATE, TRUE, 0);
  183.     }
  184.     if(year < 0 || year > 19)
  185.         CASError(CASBADDATE, TRUE, 0);
  186.  
  187.     /* Sqeeze the date into a single word. */
  188.     w_date = day | (month << 5) | (year << 9);
  189.     return(w_date);
  190.  
  191. }
  192.  
  193. /*---------------------------------------------------------------------------*
  194.  *                                SendSingle()                               *
  195.  *---------------------------------------------------------------------------*
  196.  * Send a single file. This function is called when the command line contains*
  197.  * only one file to send. Most options can be changed from the command line. *
  198.  *---------------------------------------------------------------------------*
  199.  * Parameters:  char *filename - Name of file to send.                       *
  200.  *              SFTR *SFTRbuffer - Filled in SFTR structure.                 *
  201.  * Return:      Event handle.                                                *
  202.  *---------------------------------------------------------------------------*/
  203. SendSingle(char *filename, SFTR *SFTRbuffer)
  204. {
  205.     int CharsUsed = 0;              /* Number of chars in cover text.        */
  206.     int EventHandle;                /* Event handle returned from CAS.       */
  207.     int i;                          /* Loop Counter.                         */
  208.     int spaceleft;                  /* Keeps track of space used in cover.   */
  209.     FILE *fh;                       /* DOS file handle of cover file.        */
  210.     char c[2];                      /* Char to read cover file into.         */
  211.     struct stat fbuffer;            /* DOS stat structure.                   */
  212.  
  213.     c[1] = '\0';
  214.     /* Lets set the entire buffer to a known state. */
  215.     strnset((char *)SFTRbuffer, '\0', sizeof(SFTR));
  216.  
  217.  
  218.     if(FileMode)                                    /* TransferType        0 */
  219.         SFTRbuffer->TransferType = FILE_TRANSFER;
  220.     else if (HiRes)
  221.         SFTRbuffer->TransferType = FAX_200;
  222.     else
  223.         SFTRbuffer->TransferType = FAX_100;
  224.  
  225.     if(!FileMode && WideFont)
  226.         SFTRbuffer->TextSize = 1;                   /* TextSize 132 col    1 */
  227.     else
  228.         SFTRbuffer->TextSize = 0;                   /*           80 col      */
  229.  
  230.     SFTRbuffer->EventTime = GetTime(SendTime);      /* EventTime           2 */
  231.     SFTRbuffer->EventDate = GetDate(SendDate);      /* EventDate           4 */
  232.     strncpy(SFTRbuffer->DestinationName, Phone, 31);/* DestinationName     6 */
  233.     strncpy(SFTRbuffer->FileName, filename, 79);    /* FileName           38 */
  234.     strncpy(SFTRbuffer->Phone, Phone,46);           /* Phone             118 */
  235.     strncpy(SFTRbuffer->ApplicationTag, "CCSEND", 63); /* ApplicationTag 165 */
  236.     SFTRbuffer->RESERVED1 = 0;                      /* RESERVED1         229 */
  237.  
  238.     if((Cover == NULL) && (CoverFile == NULL))      /* SendCover         230 */
  239.         SFTRbuffer->SendCover = NO_COVER;
  240.     else
  241.         SFTRbuffer->SendCover = COVER;
  242.  
  243.     strnset(SFTRbuffer->RESERVED2, '\0', 23);       /* RESERVED2         231 */
  244.  
  245.     /* Copy the cover page text (first from the command line, then from the
  246.        specified cover page file  254 */
  247.     if(strlen(Cover) != 0) {
  248.         CharsUsed = strlen(Cover) + 2;
  249.         strcpy(&SFTRbuffer->CoverTextDummy, Cover);
  250.         strcat(&SFTRbuffer->CoverTextDummy, "\n\n");
  251.         if(strlen(CoverFile) == 0)
  252.             strcat(&SFTRbuffer->CoverTextDummy, "\0");
  253.     }
  254.     else
  255.         CharsUsed = 0;
  256.  
  257.     if(strlen(CoverFile) != 0) {
  258.         /* If cover file was specified, read it into SFTR after the command
  259.            line specified cover text. */
  260.         if(!IsASCIIFile(CoverFile))
  261.             CASError(CASBADCOVERFILE, TRUE, 0);
  262.  
  263.         if((fh = fopen(CoverFile, "r")) == NULL)
  264.             CASError(CASOPENTEMP, TRUE, 0);
  265.         else {
  266.             fstat(fileno(fh), &fbuffer);
  267.             if(strlen(Cover) == 0)
  268.                 strcpy(&SFTRbuffer->CoverTextDummy, "");
  269.             for(i = ++CharsUsed; (i < 2880) && (i < fbuffer.st_size); i++) {
  270.                 fread(&c[0], 1, 1, fh);
  271.                 strcat(&SFTRbuffer->CoverTextDummy, c);
  272.             }
  273.             strcat(&SFTRbuffer->CoverTextDummy, "\0"); /* ASCIIZ terminator */
  274.             fclose(fh);
  275.         }
  276.     }
  277.  
  278.     if((EventHandle = CASSubmitSingleFile(SFTRbuffer)) > 0)
  279.         return(EventHandle);
  280.     else
  281.         CASError(CASSEND, TRUE, -EventHandle);
  282.  
  283. }
  284.  
  285. /*---------------------------------------------------------------------------*
  286.  *                                FillTCF()                                  *
  287.  *---------------------------------------------------------------------------*
  288.  * Fills in an ECF structure in preperation to save it as a Task Control     *
  289.  * file.                                                                     *
  290.  *---------------------------------------------------------------------------*
  291.  * Parameters:  ECF *TCFbuffer - Uninitialized ECF structure.                *
  292.  *              int file_count - Number of files to send.                    *
  293.  * Return:      int value indicating the maximum cover file size.            *
  294.  *---------------------------------------------------------------------------*/
  295. int FillTCF(ECF *TCFbuffer, int file_count)
  296. {
  297.     int textsize;                   /* Size of cover text on command line.   */
  298.     int filesize;                   /* Sixe of cover file.                   */
  299.     struct stat fbuffer;            /* DOS stat buffer.                      */
  300.  
  301.     /* Lets set the entire buffer to a known state. */
  302.     strnset((char *)TCFbuffer, '\0', sizeof(ECF));
  303.  
  304.     TCFbuffer->EventType = SEND;                    /* EventType           0 */
  305.  
  306.     if(FileMode)                                    /* TransferType        1 */
  307.         TCFbuffer->TransferType = FILE_TRANSFER;
  308.     else if (HiRes)
  309.         TCFbuffer->TransferType = FAX_200;
  310.     else
  311.         TCFbuffer->TransferType = FAX_100;
  312.  
  313.     TCFbuffer->EventStatus = 0;                     /* EventStatus         2 */
  314.     TCFbuffer->EventTime = GetTime(SendTime);       /* EventTime           4 */
  315.     TCFbuffer->EventDate = GetDate(SendDate);       /* EventDate           6 */
  316.     TCFbuffer->FileCount = file_count;              /* FileCount           8 */
  317.  
  318.     /* Have to get the size of the cover text (/m) if any. Add 4 to account
  319.        for two newlines that will be appended to the cover text. */
  320.     if(Cover) {
  321.         textsize = strlen(Cover) + 2;
  322.     }
  323.     else
  324.         textsize = 0;
  325.  
  326.     /* Have to get the size of the cover file if any. */
  327.     if(CoverFile) {
  328.         stat(CoverFile, &fbuffer);
  329.         if(fbuffer.st_size + textsize > 2880)
  330.             filesize = 2880 - textsize;
  331.         else
  332.             filesize = fbuffer.st_size;
  333.     }
  334.     else
  335.         filesize = 0;
  336.  
  337.     TCFbuffer->FTROffset = 383 + textsize + filesize;
  338.     if(Cover || CoverFile)
  339.         /* Have to account for the null character that will be appended by
  340.            adding 1 to the total length. */         /* FTROffset          10 */
  341.         TCFbuffer->FTROffset++;
  342.  
  343.     strncpy(TCFbuffer->Phone, Phone, 46);             /* Phone            12 */
  344.     strncpy(TCFbuffer->ApplicationTag, "CCSEND", 63); /* ApplicationTag   59 */
  345.     TCFbuffer->RESERVED1 = 0;                       /* RESERVED1         123 */
  346.     TCFbuffer->ConnectSeconds = 0;                  /* ConnectSeconds    124 */
  347.     TCFbuffer->ConnectMinutes = 0;                  /* ConnectMinutes    125 */
  348.     TCFbuffer->ConnectHours = 0;                    /* ConnectHours      126 */
  349.     TCFbuffer->TotalPages = 0;                      /* TotalPages        127 */
  350.     TCFbuffer->PagesSent = 0;                       /* PagesSent         131 */
  351.     TCFbuffer->FilesSent = 0;                       /* FilesSent         135 */
  352.  
  353.     if((Cover == NULL) && (CoverFile == NULL) && (Logo == NULL)) /* SendCover    137 */
  354.         TCFbuffer->SendCover = NO_COVER;
  355.     else
  356.         TCFbuffer->SendCover = COVER;
  357.  
  358.     TCFbuffer->ErrorCount = 0;                      /* ErrorCount        138 */
  359.     strnset(TCFbuffer->RESERVED2, '\0', 78);        /* RESERVED2         140 */
  360.     strnset(TCFbuffer->RemoteCSID, '\0', 21);       /* RemoteCSID        218 */
  361.     strncpy(TCFbuffer->DestinationName, Phone, 31); /* DestinationName   239 */
  362.                                                     /* SenderName        271 */
  363.     strncpy(TCFbuffer->SenderName, EDBbuffer->DefaultSender, 31);
  364.  
  365.     if(strcmpi(Logo,"default") == 0) {              /* LogoFilePath      303 */
  366.         strcpy(TCFbuffer->LogoFilePath, EDBbuffer->DefaultDir);
  367.         strcat(TCFbuffer->LogoFilePath, EDBbuffer->DefaultLogo);
  368.         }
  369.     else
  370.         if(strlen(Logo) == 0)
  371.             strnset(TCFbuffer->LogoFilePath, '\0', 80);
  372.         else
  373.             if(IsPCXFile(Logo))
  374.                 strncpy(TCFbuffer->LogoFilePath, Logo, 79);
  375.             else
  376.                 CASError(CASBADLOGOFILE, TRUE, 0);
  377.  
  378. }
  379.  
  380. /*---------------------------------------------------------------------------*
  381.  *                                 FillFTR()                                 *
  382.  *---------------------------------------------------------------------------*
  383.  * Fills in an array of FTR structures in preperation for creating a Task    *
  384.  * Control file.                                                             *
  385.  *---------------------------------------------------------------------------*
  386.  * Parameters:  char *filename - Name of file to transfer.                   *
  387.  *              FTR *FTRbuffer[] - Array of FTR structures.                  *
  388.  *              int num - File number (1-first, 2-second...)                 *
  389.  * Return:      none                                                         *
  390.  *---------------------------------------------------------------------------*/
  391. FillFTR(char *filename, FTR *FTRbuffer[], int num)
  392. {
  393.     char *CurrentDir;               /* Current working directory.            */
  394.  
  395.     /* Lets set the entire buffer to a known state. */
  396.     strnset((char *)FTRbuffer[num], '\0', sizeof(FTR));
  397.  
  398.     FTRbuffer[num]->FileType = 0;                   /* FileType           0 */
  399.     if(!FileMode && WideFont)
  400.         FTRbuffer[num]->TextSize = 1;               /* TextSize 132 col   1 */
  401.     else
  402.         FTRbuffer[num]->TextSize = 0;               /*           80 col     */
  403.     FTRbuffer[num]->FileStatus = 0;                 /* FileStatus         2 */
  404.     FTRbuffer[num]->BytesSent = 0;                  /* BytesSent          3 */
  405.     FTRbuffer[num]->FileSize = 0;                   /* FileSize           7 */
  406.     FTRbuffer[num]->PagesSent = 0;                  /* PagesSent         11 */
  407.     FTRbuffer[num]->PageCount = 0;                  /* PageCount         13 */
  408.     if(strpbrk(filename, "\\:") == NULL) {          /* FileName          15 */
  409.         if(getcwd(CurrentDir, 80) == NULL)
  410.                 CASError(CASBADCWD, TRUE, 0);
  411.         else {
  412.             strcpy(FTRbuffer[num]->FileName, CurrentDir);
  413.             /* Did the current dir end with a backslash? If not, append one. */
  414.             if(CurrentDir[strlen(CurrentDir) - 1] != '\\')
  415.                 strcat(FTRbuffer[num]->FileName, "\\");
  416.             strcat(FTRbuffer[num]->FileName, filename);
  417.         }
  418.     }
  419.     else
  420.         strcpy(FTRbuffer[num]->FileName, filename);
  421.  
  422.     FTRbuffer[num]->AddPageIncrements = 0;          /* AddPageIncrements 95 */
  423.     FTRbuffer[num]->PageLength = 0;                 /* PageLength        96 */
  424.     strnset(FTRbuffer[num]->RESERVED, ' ', 31);     /* RESERVED          97 */
  425.  
  426. }
  427.  
  428. /*---------------------------------------------------------------------------*
  429.  *                              SendMultiple()                               *
  430.  *---------------------------------------------------------------------------*
  431.  * Set up an event for CAS. First, write out the TCF and FTR structures to   *
  432.  * a Task Control file. Next, copy any cover text to it. Once the file is    *
  433.  * written, it is submitted to CAS with CASSubmitTask().                     *
  434.  *---------------------------------------------------------------------------*
  435.  * Parameters:  ECF *TCFbuffer - Filled in ECF structure.                    *
  436.  *              FTR *FTRbuffer[] - Filled in FTR structure array.            *
  437.  * Return:      Event Handle of the submitted task.                          *
  438.  *---------------------------------------------------------------------------*/
  439. SendMultiple(ECF *TCFbuffer, FTR *FTRbuffer[])
  440. {
  441.     int result, i;                  /* Function return - Loop counter.       */
  442.     int CharsUsed = 0;              /* Number of chars in cover text.        */
  443.     int EventHandle;                /* Event handle returned from CAS.       */
  444.     int ErrorCode;                  /* Error return from CAS functions.      */
  445.     int spaceleft;                  /* Keeps track of space on cover page.   */
  446.     char name[13];                  /* Temporary file name.                  */
  447.     FILE *fp;                       /* DOS handle for temp TCF file.         */
  448.     FILE *fh;                       /* DOS handle for cover text file.       */
  449.     char c[2];                      /* Used in reading cover file.           */
  450.     struct stat fbuffer;            /* DOS stat structure.                   */
  451.     char *TCFfile;                  /* Name of temp file.                    */
  452.  
  453.     TCFfile = (char *)malloc(62);
  454.     if(TCFfile == NULL)
  455.        CASError(CASNOMEM, TRUE, 0);
  456.  
  457.     /* Build a temp file name then open the temp file for the TCF & FTR
  458.        structure. */
  459.     strcpy(name, TEMPLATE);
  460.     if(mktemp(name) == NULL)
  461.         CASError(CASCREATETEMP, TRUE, 0);
  462.  
  463.     /* Set up the TCF filename. The temp file is placed in the default
  464.        directory as specified by the CASGetExternalData function. */
  465.     strcpy(TCFfile, EDBbuffer->DefaultDir);
  466.     strcat(TCFfile, name);
  467.  
  468.     if((fp = fopen(TCFfile, "wb")) == NULL)
  469.         CASError(CASOPENTEMP, TRUE, 0);
  470.  
  471.     /* Write the TCF structures to disk. */
  472.     fwrite(TCFbuffer, sizeof(ECF), 1, fp);
  473.  
  474.     /* Copy the cover page text (first from the command line, then from the
  475.        specified cover page file  254 */
  476.     if(strlen(Cover) != 0) {
  477.         CharsUsed = strlen(Cover) + 2;
  478.         fwrite(Cover, strlen(Cover), 1, fp);
  479.         fwrite("\n\n", 2, 1, fp);
  480.         if(strlen(CoverFile) == 0)
  481.             fwrite("\0", 1, 1, fp);
  482.     }
  483.     else
  484.         CharsUsed = 0;
  485.  
  486.     if(strlen(CoverFile) != 0) {
  487.         /* If cover file was specified, put it in the ECF after the command
  488.            line specified cover text. */
  489.         if(!IsASCIIFile(CoverFile)) {
  490.             fclose(fp);
  491.             unlink(TCFfile);
  492.             CASError(CASBADCOVERFILE, TRUE, 0);
  493.         }
  494.  
  495.         if((fh = fopen(CoverFile, "r")) == NULL)
  496.             CASError(CASBADFILEARG, TRUE, 0);
  497.         else {
  498.             fstat(fileno(fh), &fbuffer);
  499.             for (i = ++CharsUsed; (i < TCFbuffer->FTROffset - 383); i++) {
  500.                 fread(&c[0], 1, 1, fh);
  501.                 fwrite(&c[0], 1, 1, fp);
  502.             }
  503.             fclose(fh);
  504.             fwrite("\0", 1, 1, fp);
  505.         }
  506.     }
  507.  
  508.     /* Write the FTR structure(s) to disk. */
  509.     for(i = TCFbuffer->FileCount - 1; i >= 0; i--)
  510.         fwrite(FTRbuffer[i], sizeof(FTR), 1 ,fp);
  511.  
  512.     fclose(fp);
  513.  
  514.     if((EventHandle = CASSubmitTask(TCFfile)) > 0)
  515.         return(EventHandle);
  516.     else {
  517.         /* Don't forget to clean up temp file on errors! */
  518.         unlink(TCFfile);
  519.         CASError(CASSEND, TRUE, -EventHandle);
  520.     }
  521. }
  522.  
  523. /*---------------------------------------------------------------------------*
  524.  *                               Is ASCII File?                              *
  525.  *---------------------------------------------------------------------------*
  526.  *  is_ASCII determines whether the file is ASCII by looking for non_ASCII   *
  527.  *  values, i.e. certain values < 32.  If it finds one, the function returns *
  528.  *  0.  If not, a file handle for the open file is returned.                 *
  529.  *---------------------------------------------------------------------------*
  530.  *  INPUT :  event handle of RCF, file number in FTR chain                   *
  531.  *  OUTPUT:  returns DOS file handle if file is ASCII, 0 if not              *
  532.  *---------------------------------------------------------------------------*/
  533. int IsASCIIFile(char *FileName)
  534. {
  535.     FILE *fh;                       /* DOS file handle - file to test.       */
  536.     unsigned char c;                /* Used to read file.                    */
  537.  
  538.     if((fh = fopen(FileName, "r")) == NULL)
  539.         return(FALSE);
  540.  
  541.     while((fread(&c, 1, 1, fh) > 0))
  542.         if ((c < 32) && (c != 0x0A) && (c != 0x0C) && (c != 0x0D) &&
  543.                                            (c != 0x1A) && c != 0x09) {
  544.             fclose(fh);
  545.             return(FALSE);                      /* File is not ASCII. */
  546.         }
  547.  
  548.    fclose(fh);
  549.    return(TRUE);                                /* File is ASCII. */
  550. }
  551.  
  552. /*---------------------------------------------------------------------------*
  553.  *                               Is .DCX File?                               *
  554.  *---------------------------------------------------------------------------*
  555.  *  is_DCX checks for the DCX header.  If it finds it the function returns   *
  556.  *  the file_handle, otherwise 0.                                            *
  557.  *---------------------------------------------------------------------------*
  558.  *  INPUT :  event handle of RCF, file number in FTR chain                   *
  559.  *  OUTPUT:  returns DOS file handle if file is .DCX, 0 if not               *
  560.  *---------------------------------------------------------------------------*/
  561. int IsDCXFile(char *FileName)
  562. {
  563.     FILE *fh;                       /* DOS file handle - file to test.       */
  564.     union {
  565.         char buff[4];
  566.         long id;
  567.     } DCXHeader;                    /* DCX file signature.                   */
  568.  
  569.     if((fh = fopen(FileName, "r")) == NULL)
  570.         return(FALSE);
  571.  
  572.     fread(&DCXHeader, 4, 1, fh);            /* Read four bytes from file. */
  573.     fclose(fh);
  574.  
  575.     if(DCXHeader.id == DCXID)               /* Check for .DCX header. */
  576.        return(TRUE);                        /* File is .DCX. */
  577.     else
  578.        return(FALSE);                       /* File is not .DCX. */
  579. }
  580.  
  581. /*---------------------------------------------------------------------------*
  582.  *                               Is .PCX File?                               *
  583.  *---------------------------------------------------------------------------*
  584.  *  is_PCX checks for the PCX header, returning a file handle if the header  *
  585.  *  is there, 0 if not.                                                      *
  586.  *---------------------------------------------------------------------------*
  587.  *  INPUT :  event handle of RCF, file number in FTR chain                   *
  588.  *  OUTPUT:  returns DOS file handle if file is .PCX, 0 if not               *
  589.  *---------------------------------------------------------------------------*/
  590. int IsPCXFile(char *FileName)
  591. {
  592.     FILE *fh;                       /* DOS file handle - file to test.       */
  593.     char PCXid;                     /* PCX file signature.                   */
  594.     char Version;                   /* PCX ...                               */
  595.     char Encode;                    /* PCX ...                               */
  596.  
  597.     if((fh = fopen(FileName, "r")) == NULL)
  598.         return(FALSE);
  599.  
  600.     fread(&PCXid, 1, 1, fh);               /* Read first byte in file. */
  601.     fread(&Version, 1, 1, fh);             /* Throw away second byte. */
  602.     fread(&Encode, 1, 1, fh);              /* Read third byte. */
  603.     fclose(fh);
  604.  
  605.     if((PCXid == PCXID) && (Encode == PCXENCODE))
  606.        return(TRUE);                       /* File is .PCX. */
  607.     else
  608.        return(FALSE);                      /* File is not .PCX. */
  609. }
  610.  
  611. /*---------------------------------------------------------------------------*
  612.  *                                  Main                                     *
  613.  *---------------------------------------------------------------------------*
  614.  * Submit tasks to CAS for FAX or File Transfer sends. First grab the        *
  615.  * required buffers, fill in the TCF and FTR structures. If only a single    *
  616.  * file is specified on the command line, then these structures can be       *
  617.  * submitted directly to CAS. Otherwise, write the TCF and FTR structures    *
  618.  * to a disk file (a Task Control File).                                     *
  619.  *---------------------------------------------------------------------------*
  620.  * Return: The DOS exit code is 0 if no errors are encountered, 1 for        *
  621.  *         commandline syntax errors, 2 for CCAM error, and 3 for DOS        *
  622.  *         errors.                                                           *
  623.  *---------------------------------------------------------------------------*/
  624. main(int argc, char **argv)
  625. {
  626.     int result;                     /* DOS & CAS function return value.      */
  627.     int handle;                     /* Event handle returned from CAS.       */
  628.     int nfiles;                     /* Number of files to send.              */
  629.     char Name[80];                  /* File name(s) from command line.       */
  630.  
  631.     /* Get command line arguments. On return, the options have been removed
  632.        from the command line leaving only the filename(s) and address. */
  633.     argc = ParseCommand(argc, argv, SwitchTable, TABLESIZE);
  634.  
  635.     /*If help is wanted, print info and exit (with 0 exit code). */
  636.     if(Help || (argc == 1))
  637.         CASHelp(DescTable, DESCSIZE, HelpTable, HELPSIZE);
  638.  
  639.     /* At a minimum, one filename must be specified on the command line. */
  640.     if(argc < 2)
  641.         CASError(CASARGFILE, TRUE, 0);
  642.  
  643.     /* Check to see if the resident scheduler has been installed. */
  644.     if((result = CASGetInstalledState()) != INSTALLED)
  645.         if(result == NOTiOK)
  646.             CASError(CASNOHWO, TRUE, 0);
  647.         else
  648.             CASError(CASNOHWN, TRUE, 0);
  649.  
  650.     /* Redirect stdout to a file. */
  651.     if(RedirOut) {
  652.         if((ccout = fopen("OUTPUT.CC", "w")) == NULL)
  653.             CASError(CASOPENTEMP, TRUE, 0);
  654.         if(-1 == dup2(fileno(ccout), 1))
  655.             CASError(CASBADREDIR, TRUE, 0);
  656.     }
  657.  
  658.     /* Get buffer for Extended data. */
  659.     EDBbuffer = (EDB *)malloc(sizeof(EDB));
  660.     if(EDBbuffer == NULL)
  661.         CASError(CASNOMEM, TRUE, 0);
  662.  
  663.     /* Get External Data Block (ie: path to default logo etc.). */
  664.     if(CASGetExternalData(EDBbuffer) != 0)
  665.         CASError(CASNOEDB, TRUE, 0);
  666.  
  667.     /* If argc = 2, then only one filename has been specified and we can
  668.        use the more efficient send_single command. Otherwise, we need to
  669.        build an TCF with multiple FTRs. */
  670.     if((argc == 2) && (Logo == NULL)) {
  671.         ++argv;
  672.         strcpy(Name, *argv);
  673.  
  674.         /* Specified files must be of the correct type! ASCII, PCX, or DCX for
  675.            Faxes, ASCII, PCX, DCX, or binary for file transfers. */
  676.         if(access(Name, 0) == -1)
  677.             CASError(CASBADFILEARG, TRUE, 0);
  678.         if(!FileMode)
  679.             if(!IsPCXFile(*argv) && !IsDCXFile(*argv) && !IsASCIIFile(*argv))
  680.                 CASError(CASBADFAXFILE, TRUE, 0);
  681.  
  682.         /* Allocate a buffer large enough to hold an SFTR structure. */
  683.         SFTRbuffer = (SFTR *)malloc(sizeof(SFTR));
  684.         if(SFTRbuffer == NULL)
  685.             CASError(CASNOMEM, TRUE, 0);
  686.  
  687.         /* Point to filename on commnd line and send it! */
  688.         handle = SendSingle(Name, SFTRbuffer);
  689.         fprintf(stdout, "Send submitted successfully.\nEvent number is %d\n", handle);
  690.     }
  691.     else {
  692.         /* Number of files to send (argc - 1). */
  693.         nfiles = argc - 1;
  694.         argv++;
  695.  
  696.         /* Allocate a buffer large enough to hold an TCF structure. */
  697.         TCFbuffer = (ECF *)malloc(sizeof(ECF));
  698.         if(TCFbuffer == NULL)
  699.             CASError(CASNOMEM, TRUE, 0);
  700.  
  701.         FillTCF(TCFbuffer, nfiles);
  702.  
  703.         /* For each file to send, create a File Transfer Record. */
  704.         while(argc > 1) {
  705.             /* Specified files must be of the correct type! ASCII, PCX, or DCX for
  706.                Faxes, ASCII, PCX, DCX, or binary for file transfers. */
  707.             strcpy(Name, *argv);
  708.             if(access(Name, 0) == -1) {
  709.                 fprintf(stderr, "%s : ", strupr(Name));
  710.                 CASError(CASBADFILEARG, TRUE, 0);
  711.             }
  712.             if(!FileMode)
  713.                 if(!IsPCXFile(Name) && !IsDCXFile(Name) && !IsASCIIFile(Name))
  714.                     CASError(CASBADFAXFILE, TRUE, 0);
  715.  
  716.             /* Allocate a buffer large enough to hold an FTR structure. */
  717.             FTRbuffer[argc - 2] = (FTR *)malloc(sizeof(FTR));
  718.             if(FTRbuffer[argc - 2] == NULL)
  719.                 CASError(CASNOMEM, TRUE, 0);
  720.  
  721.             /* Fill in the FTR for each file. */
  722.             FillFTR(Name, FTRbuffer, (argc - 2));
  723.  
  724.             /* Point to filename on command line, reduce file count. */
  725.             ++argv; --argc;
  726.         }
  727.         handle = SendMultiple(TCFbuffer, FTRbuffer);
  728.         fprintf(stdout, "Send submitted successfully.\nEvent number is %d\n", handle);
  729.     }
  730.  
  731.     exit(0);
  732. }
  733.